<?php

namespace App\Model;

use App\Common\Exception\ThrowException;
use App\Common\Library\GoogleAuthenticator;

class  Member extends BaseModel
{

    const REIDS_KEY = 'MEMBER:TOKEN:';

    /**
     * 用户中心表
     * @return UcenterMember
     */
    public function getUcenterMemberMoudel()
    {
        return new UcenterMember();
    }

    /**
     * 获取配置.
     * @return Config
     */
    public function getConfigMoudel()
    {
        return new Config();
    }

    /**
     * 用户登陆
     * @param $datas
     */
    public function login($data)
    {
        $ucenterMemberInfo = $this->getUcenterMemberMoudel()->findOne(['username' => $data['username']]);
        if (!$ucenterMemberInfo) {
            throw new ThrowException(ThrowException::EROOR_MEMBER_LOGIN_USER_NOT);
        }
        if ($ucenterMemberInfo['status'] == 0) {
            throw new ThrowException(ThrowException::EROOR_MEMBER_LOGIN_STATUS_DISABLE);
        }
        if ($ucenterMemberInfo['status'] == 0) {
            throw new ThrowException(ThrowException::EROOR_MEMBER_LOGIN_STATUS_DISABLE);
        }
        if ($ucenterMemberInfo['status'] == -1) {
            throw new ThrowException(ThrowException::EROOR_MEMBER_LOGIN_DELELTE);
        }
        $password = $data["password"];
        if ($ucenterMemberInfo['password'] !== lzy_ucenter_md5($password, \EasySwoole\EasySwoole\Config::getInstance()->getConf('DATA_AUTH_KEY'))) {
            throw new ThrowException(ThrowException::EROOR_MEMBER_LOGIN_PASSWORD);
            return false;
        }
        //判断是否是google 认证
        $check_otp = $this->getConfigMoudel()->getConfigKeyName("BACKEND_SWITCH_OTP");
        $member = $this->findOne(['uid' => $ucenterMemberInfo['id']]);
        if ($check_otp) {
            //判断会员验证是否为空
            if (empty($member['member->otp_gg'])) {
                throw new ThrowException(ThrowException::EROOR_OPT_RE_URL); //跳转到绑定页面
            }
            $vercode = $data["vercode"];
            if (empty($vercode)) {
                throw new ThrowException(ThrowException::EROOR_OPT_EMPTY_CODE); //验证码不能为空
            }
            $otpGg = $this->getGoogleCode($member['otp_gg']);
            if ($otpGg != $data['vercode']) {
                throw new ThrowException(ThrowException::EROOR_OPT_CODE);//OTP验证码错误
            }
        }
//        $remember=empty($data["remember"])?'':$data["remember"];
//        if($remember=='on'){  //如果打开记住密码，则放到cookie中去
//            $this->setLoginCookie($ucenterMemberInfo,$member);
//        }

        return $this->updateLogin($ucenterMemberInfo, $member);//更新用户信息;
    }

    /**
     * 更新用户token
     * @param $ucenterMemberInfo
     */
    public function updateLogin($ucenterMemberInfo, $member)
    {
//        $auth = array(
//            'uid' => $ucenterMemberInfo['id'],
//            'username' => $ucenterMemberInfo['username'],
//            'nickname' => $member['nickname'],
//            'logo' => $member['logo']
//        );
//        $_SESSION['lzysys_auth'] = $auth;
//        $_SESSION['lzysys_auth_sign'] = data_auth_sign($auth);
        // 用户行为操作
        //登陆记录到登陆表中去
        action_log("user_login", "Member", $ucenterMemberInfo['id'], $ucenterMemberInfo['id']);
        return $this->genToken(32, true, $ucenterMemberInfo['id']);
    }

    /**
     * 记住密码操作
     * @param $ucenterMemberInfo
     */
    public function setLoginCookie($ucenterMemberInfo, $member)
    {

        $auth = array(
            'uid' => $ucenterMemberInfo['id'],
            'username' => $ucenterMemberInfo['username'],
            'nickname' => $member['nickname'],
            'logo' => $member['logo']
        );
        $cookies_expire = 3600 * 24 * 365;  //cookie 进期时间
        setcookie('admin_uid', $ucenterMemberInfo['id'], $cookies_expire);  //用户id
        setcookie('admin_username', $ucenterMemberInfo['username'], $cookies_expire); //用户名
        setcookie('admin_nickname', $member['nickname'], $cookies_expire); //用户昵称
        setcookie('admin_logo', $member['logo'], $cookies_expire);    //用户头像
        setcookie('lqwsys_auth_sign', data_auth_sign($auth), $cookies_expire);    //加密串

    }

    /**
     * 获取验证码
     * @param $code
     * @return string
     */
    public function getGoogleCode($code)
    {
        $ga = new GoogleAuthenticator();
        $oneCode = $ga->getCode($code); //服务端计算"一次性验证码"
        return $oneCode;
    }

    /**
     * 获取邦定串
     * @return string
     */
    public function getGoogleSecret()
    {
        $ga = new GoogleAuthenticator();
        //创建一个新的"安全密匙SecretKey"
        //把本次的"安全密匙SecretKey" 入库,和账户关系绑定,客户端也是绑定这同一个"安全密匙SecretKey"
        $secret = $ga->createSecret();
        return $secret;

    }


    /**
     * 更新google二维码
     * @param $data
     * @return int|mixed
     * @throws MemberException
     */
    public function bindGoogleOtp($data)
    {
        $username = session('lqwsys_member_username');  //登陆用户名
        if (empty($username)) {
            throw  new ThrowException(ThrowException::EROOR_MEMBER_LOGIN_USER_NOT);
        }
        //然后加上
        $uMemberInfo = $this->where("username", $username)->first();
        if (empty($uMemberInfo)) {
            throw new ThrowException(ThrowException::EROOR_MEMBER_LOGIN_USER_NOT);
        }
        //更新邦定
        return $this->where("uid", $uMemberInfo->id)->update(["otp_gg" => $data['secret']]);
    }

    /**
     * 获取一个token值
     * @param int $len 长度，默认32位
     * @param bool $md5 默认使用md5算法
     * @param int $uid 用户uid
     * @return string 一个32为的token串
     */
    function genToken($len = 32, $md5 = true, $uid = 0)
    {
        # Seed random number generator
        # Only needed for PHP versions prior to 4.2
        mt_srand((double)microtime() * 1000000);
        # Array of characters, adjust as desired
        $chars = array(
            'Q', '@', '8', 'y', '%', '^', '5', 'Z', '(', 'G', '_', 'O', '`',
            'S', '-', 'N', '<', 'D', '{', '}', '[', ']', 'h', ';', 'W', '.',
            '/', '|', ':', '1', 'E', 'L', '4', '&', '6', '7', '#', '9', 'a',
            'A', 'b', 'B', '~', 'C', 'd', '>', 'e', '2', 'f', 'P', 'g', ')',
            '?', 'H', 'i', 'X', 'U', 'J', 'k', 'r', 'l', '3', 't', 'M', 'n',
            '=', 'o', '+', 'p', 'F', 'q', '!', 'K', 'R', 's', 'c', 'm', 'T',
            'v', 'j', 'u', 'V', 'w', ',', 'x', 'I', '$', 'Y', 'z', '*'
        );
        # Array indice friendly number of chars;
        $numChars = count($chars) - 1;
        $token = '';
        # Create random token at the specified length
        for ($i = 0; $i < $len; $i++)
            $token .= $chars[mt_rand(0, $numChars)];
        # Should token be run through md5?
        if ($md5) {
            # Number of 32 char chunks
            $chunks = ceil(strlen($token) / 32);
            $md5token = '';
            # Run each chunk through md5
            for ($i = 1; $i <= $chunks; $i++)
                $md5token .= md5(substr($token, $i * 32 - 32, 32));
            # Trim the token
            $token = substr($md5token, 0, $len);
        }

        $arr = [];
        $arr['uid'] = $uid;
        $arr['token'] = md5($uid);//$token;
        $string = json_encode($arr);
        return base64_encode($string);
    }

    public function logout($uid)
    {
        $this->getRedis()->del(self::REIDS_KEY . $uid);
    }

    /**
     * 列表
     * @return mixed
     */
    public function getList($data, $where)
    {
        $limit = $data['limit'] ?? 10;
        $condition = $this->analysisWhere($where);
        return $this->getPageAll($condition, $data['page'], $limit);
    }

    /**
     * 新增一条用户信息
     * @param $data
     * @return mixed|void
     */
    public function addMemberInfoRow($data)
    {
        $password = $data["password"];
        $repassword = $data["repassword"];
        if ($password !== $repassword) {
            throw  new ThrowException(ThrowException::EROOR_MEMBER_SAVE_PASSWORD_SAME);
        }
        //判断帐号是否存在
        if (!empty($this->getUcenterMemberFindFiled(["username" => $data["username"]], "username"))) {
            throw  new ThrowException(ThrowException::EROOR_MEMBER_ACCOUNT_ISEXIT);
        }
        //判断手机号是否存在
        if (!empty($this->getUcenterMemberFindFiled(["mobile" => $data["mobile"]], "mobile"))) {
            throw  new ThrowException(ThrowException::EROOR_MEMBER_MOBILE_ISEXIT);
        }
        $udata = array();
        $udata["username"] = $data["username"];
        $udata["password"] = lzy_ucenter_md5($password, \EasySwoole\EasySwoole\Config::getInstance()->getConf('lzy.DATA_AUTH_KE'));
        $udata["mobile"] = $data["mobile"];
        $udata["reg_time"] = time();
        $udata["reg_ip"] = getClientIp(1);


        if ($uid = $this->getUcenterMemberMoudel()->addData($udata)) {
            $mdata = array();
            $mdata["uid"] = $uid;
            $mdata["nickname"] = $data["nickname"];
            $mdata["logo"] = $data["logo"];
            $mdata["sex"] = empty($data["sex"]) ? 0 : 1;
            $mdata["birthday"] = $data["birthday"];
            return $this->addData($mdata);
        } else {
            throw new ThrowException(ThrowException::EROOR_MEMBER_SAVE);
        }
    }

    public function updateMemberInfoRow($data){

        $password = $data["password"];
        $where=array();
        $where['username'] = $data['username'];
        $where['id|<>'] = $data["uid"];
        //判断帐号是否存在
        if (!empty($this->getUcenterMemberFindFiled($where, "username"))) {
            throw  new ThrowException(ThrowException::EROOR_MEMBER_ACCOUNT_ISEXIT);
        }
        $where=array();
        $where['mobile'] = $data['mobile'];
        $where['id|<>'] = $data["uid"];
        //判断手机号是否存在
        if (!empty($this->getUcenterMemberFindFiled($where, "mobile"))) {
            throw  new ThrowException(ThrowException::EROOR_MEMBER_MOBILE_ISEXIT);
        }

        $udata = array();
        $udata["username"] = $data["username"];
        if (!empty($password)) {
            $udata["password"] = lqw_ucenter_md5($password, config("lzy.DATA_AUTH_KEY"));
        }
        $udata["mobile"] = $data["mobile"];
        $udata["reg_time"] = time();
        $udata["reg_ip"] = getClientIp(1);
        $ucenterMember = new UcenterMember;
        if ($ucenterMember->updateOrCreateData($udata,["id" => $data["uid"]])) {
            $mdata = array();
            $mdata["nickname"] = $data["nickname"];
            $mdata["logo"] = $data["logo"];
            $mdata["sex"] = empty($data["sex"]) ? 0 : 1;
            $mdata["birthday"] = $data["birthday"];
            //清去用户缓存
            $res=$this->editData($this->analysisWhere(["uid" => $data["uid"]]),$mdata);
            return $res;
        } else {
            throw new ThrowException(ThrowException::EROOR_MEMBER_SAVE);
        }
    }

    /**
     * 查找ucenter_member是否有这张表
     * @param $where
     * @param $field
     * @return array|null
     * @throws \EasySwoole\Mysqli\Exceptions\ConnectFail
     * @throws \EasySwoole\Mysqli\Exceptions\PrepareQueryFail
     * @throws \Throwable
     */
    public function getUcenterMemberFindFiled($where,$field){
         return $this->getUcenterMemberMoudel()->getFiledValue($where,$field);
    }



    /**
     * 单条数据
     * @param $where
     * @return array|null|\PDOStatement|string|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function infoWithData($where){
        $table=$this->getUcenterMemberMoudel()->table;
        return $this->getJoinLeft($this->analysisWhere($where),$table,$this->table.'.uid='.$table.'.id');
    }

}